//
//  UtilMacro.h
//  YSKitExample
//
//  Created by MOLBASE on 2017/7/3.
//  Copyright © 2017年 YangShen. All rights reserved.
//
//  宏定义

#ifndef UtilMacro_h
#define UtilMacro_h

#import "YSConstants.h"

#pragma mark - static inline helper method
static inline CGFloat YSScreenScale() {
    static CGFloat scale;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        scale = [UIScreen mainScreen].scale;
    });
    return scale;
}

static inline CGSize YSScreenSize() {
    static CGSize size;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        size = [UIScreen mainScreen].bounds.size;
        if (size.height < size.width) {
            CGFloat tmp = size.height;
            size.height = size.width;
            size.width = tmp;
        }
    });
    return size;
}

/// 是否是iPhoneX系列
static inline BOOL YSIsIPhoneXSeries() {
    BOOL iPhoneXSeries = NO;
    if (UIDevice.currentDevice.userInterfaceIdiom != UIUserInterfaceIdiomPhone) {
        return iPhoneXSeries;
    }
    
    if (@available(iOS 11.0, *)) {
        UIWindow *mainWindow = [[[UIApplication sharedApplication] delegate] window];
        if (mainWindow.safeAreaInsets.bottom > 0.0) {
            iPhoneXSeries = YES;
        }
    }
    
    return iPhoneXSeries;
}

/// Convert degrees to radians.
static inline CGFloat YSDegreesToRadians(CGFloat degrees) {
    return degrees * M_PI / 180;
}

/// Convert radians to degrees.
static inline CGFloat YSRadiansToDegrees(CGFloat radians) {
    return radians * 180 / M_PI;
}

#pragma mark - LOG
#ifdef DEBUG
#define NSLog(FORMAT, ...) do {fprintf(stderr,"🐶 [%s] %s:%d %s 🐱  %s\n", __TIME__, [[[NSString stringWithUTF8String:__FILE__] lastPathComponent] UTF8String], __LINE__, [[[NSString stringWithUTF8String:__PRETTY_FUNCTION__] lastPathComponent] UTF8String], [[NSString stringWithFormat:FORMAT, ##__VA_ARGS__] UTF8String]);} while(0)
#else
#define NSLog(...)
#endif
// 打印方法
#define YSLogFunc NSLog(@"%s", __func__)
// 打印请求错误信息
#define YSLogError(error) NSLog(@"Error: %@", error)

#pragma mark - 应用相关
/// 应用名称
#define kAppName       ([[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleName"])
/// 应用标识
#define kAppIdentifier ([[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleIdentifier"])
/// 应用版本号
#define kAppVersion    ([[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"])
/// 应用build版本
#define kAppBuild      ([[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"])
// AppCaches 文件夹路径
#define YSCachesDirectory [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject]
// AppDocument 文件夹路径
#define YSDocumentDirectory [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES) lastObject]

#pragma mark - 系统对象
#define kApplication        [UIApplication sharedApplication]
#define kAppWindow          [UIApplication sharedApplication].delegate.window
#define kAppKeyWindow       [UIApplication sharedApplication].keyWindow
#define kAppDelegate        ((AppDelegate *)[UIApplication sharedApplication].delegate)
#define kUserDefaults       [NSUserDefaults standardUserDefaults]
#define kNotificationCenter [NSNotificationCenter defaultCenter]

#pragma mark - 类型 && 尺寸
/// 类型相关
#define k_IPAD   (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
#define k_IPHONE (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
#define k_RETINA (YSScreenScale() >= 2.0)

/// 屏幕尺寸相关
#define kScreenScale     YSScreenScale()
#define kScreenWidth     (YSScreenSize().width)
#define kScreenHeight    (YSScreenSize().height)
#define kScreenMaxLength (MAX(kScreenWidth, kScreenHeight))
#define kScreenMinLength (MIN(kScreenWidth, kScreenHeight))

#define k_PHONE_4           (k_IPHONE && kScreenMaxLength  < 568.0)
#define k_IPHONE_5          (k_IPHONE && kScreenMaxLength == 568.0)
#define k_IPHONE_6          (k_IPHONE && kScreenMaxLength == 667.0)
#define k_IPHONE_6P         (k_IPHONE && kScreenMaxLength == 736.0)
#define k_IPHONE_X          YSIsIPhoneXSeries()

/// 导航条高度
#define kNavBarH            (k_IPHONE_X?88.0f:64.0f)
/// tabBar高度
#define kTabBarH            (k_IPHONE_X?83.0f:49.0f)
/// 状态栏高度
#define kStatusBarH         (k_IPHONE_X?44:20.0f)
/// 底部安全距离
#define kBottomSalfH        (k_IPHONE_X?34:0)
/// 宽度比 375
#define kWidthRatio         (kScreenWidth / 375.0)
/// 高度比 667
#define kHeightRatio        (kScreenHeight / 667.0)
/// 适配Width
#define kAdaptive(width)    (kWidthRatio * width)

#pragma mark - iOS版本
#define kIOSVersion     ([[[UIDevice currentDevice] systemVersion] floatValue])
/// 传入的iOS系统版本及以上
#define kiOSVersionAbove(number) (kIOSVersion >= number)
/// 传入的iOS系统版本及以下
#define kiOSVersionBelow(number) (kIOSVersion <= number)
/// 传入的iOS系统版本
#define kiOSVersionEqual(number) ([[[UIDevice currentDevice] systemVersion] compare:number options:NSNumericSearch] == NSOrderedSame)

#pragma mark - 颜色
#define kRGBA(r, g, b, a) [UIColor colorWithRed:(r)/255.0 green:(g)/255.0 blue:(b)/255.0 alpha:a]
#define kRGB(r, g, b) kRGBA(r, g, b, 1.0)
/// 随机色
#define kRandomColor kRGB(arc4random_uniform(256), arc4random_uniform(256), arc4random_uniform(256))
/// 根据hex获取对应的颜色
#define kHEXA(rgbValue, a) [UIColor colorWithRed:((float)((rgbValue & 0xFF0000) >> 16))/255.0 green:((float)((rgbValue & 0xFF00) >> 8))/255.0 blue:((float)(rgbValue & 0xFF))/255.0 alpha:(a)]
#define kHEX(rgbValue) kHEXA(rgbValue, 1.0)

#pragma mark - 字体
/// 字体网址：http://iosfonts.com
#define kSystemFont(number)        [UIFont systemFontOfSize:number]
#define kBoldFont(number)          [UIFont boldSystemFontOfSize:number]
#define kCustomFont(name, number)  [UIFont fontWithName:name size:number]

#pragma mark - 图片
#define kImageNamed(imageName) [UIImage imageNamed:imageName]
#define YSLoadImage(file, ext) [UIImage imageWithContentsOfFile:[[NSBundle mainBundle]pathForResource:file ofType:ext]]

#pragma mark - nil & null
/// 是否为空对象
#define kObjectIsNil(object)  ((nil == object) || [object isKindOfClass:[NSNull class]])
/// 字符串为空
#define kStringIsEmpty(string) (YSObjectIsNil(string) || (string.length == 0))
// 数组为空
#define kArrayIsEmpty(array) ((YSObjectIsNil(array)) || (array.count == 0))

#pragma mark - GCD
#define kGCD_Global(block) dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), block)
#define kGCD_MAIN(block)   dispatch_async(dispatch_get_main_queue(), block)

#pragma mark - Helper
/// 过期提醒
#define YSDeprecated(instead) NS_DEPRECATED(2_0, 2_0, 2_0, 2_0, instead)
/// 获取一段时间间隔
#define YSStartTime CFAbsoluteTime start = CFAbsoluteTimeGetCurrent();
#define YSEndTime   NSLog(@"Time: %f", CFAbsoluteTimeGetCurrent() - start)

/// 拼接字符串
#define NSStringFormat(format,...) [NSString stringWithFormat:format,##__VA_ARGS__]

/// View 圆角和加边框
#define ViewBorderRadius(View, Radius, Width, Color)\
\
[View.layer setCornerRadius:(Radius)];\
[View.layer setMasksToBounds:YES];\
[View.layer setBorderWidth:(Width)];\
[View.layer setBorderColor:[Color CGColor]]

/// View 圆角
#define ViewRadius(View, Radius)\
\
[View.layer setCornerRadius:(Radius)];\
[View.layer setMasksToBounds:YES]

#pragma mark - weak && strong
/**
 Synthsize a weak or strong reference.
 
 Example:
 @weakify(self)
 [self doSomething^{
 @strongify(self)
 if (!self) return;
 ...
 }];
 
 */
#ifndef weakify
#if DEBUG
#if __has_feature(objc_arc)
#define weakify(object) autoreleasepool{} __weak __typeof__(object) weak##_##object = object;
#else
#define weakify(object) autoreleasepool{} __block __typeof__(object) block##_##object = object;
#endif
#else
#if __has_feature(objc_arc)
#define weakify(object) try{} @finally{} {} __weak __typeof__(object) weak##_##object = object;
#else
#define weakify(object) try{} @finally{} {} __block __typeof__(object) block##_##object = object;
#endif
#endif
#endif

#ifndef strongify
#if DEBUG
#if __has_feature(objc_arc)
#define strongify(object) autoreleasepool{} __typeof__(object) object = weak##_##object;
#else
#define strongify(object) autoreleasepool{} __typeof__(object) object = block##_##object;
#endif
#else
#if __has_feature(objc_arc)
#define strongify(object) try{} @finally{} __typeof__(object) object = weak##_##object;
#else
#define strongify(object) try{} @finally{} __typeof__(object) object = block##_##object;
#endif
#endif
#endif

/// 适配iPhone X + iOS 11
#define  YSAdjustsScrollViewInsets_Never(__scrollView)\
do {\
_Pragma("clang diagnostic push")\
_Pragma("clang diagnostic ignored \"-Warc-performSelector-leaks\"")\
if ([__scrollView respondsToSelector:NSSelectorFromString(@"setContentInsetAdjustmentBehavior:")]) {\
NSMethodSignature *signature = [UIScrollView instanceMethodSignatureForSelector:@selector(setContentInsetAdjustmentBehavior:)];\
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];\
NSInteger argument = 2;\
invocation.target = __scrollView;\
invocation.selector = @selector(setContentInsetAdjustmentBehavior:);\
[invocation setArgument:&argument atIndex:2];\
[invocation retainArguments];\
[invocation invoke];\
}\
_Pragma("clang diagnostic pop")\
} while (0)


#endif /* YSKitMacro_h */
